<?php
if (!class_exists('gtk')) {
	if (strtoupper(substr(PHP_OS, 0,3) == 'WIN'))
	dl('php_gtk.dll');
	else
	dl('php_gtk.so');
}
require_once("./clases_gtk/zen_menu_gtk.php");
require_once("./clases_gtk/zen_analizador_cartucho.php");
require_once("./clases_gtk/zen_gtk_ventana_mysql_admin.php");
define('ZF_GTK_MODO_DEBUG',true);
/**
* Clase para mostrar la ventana principal GTK del generador de aplicaciones
*/
class zen_ventana_principal extends GtkWindow
{
	/**
    * Variable para mostrar una previsualización del cartucho
    * @var str $img
    */
	var $img = null;
	/**
    * Indica si carga la vista de previsualización del cartucho definida como una ruta a una imagen dentro del XML del cartucho... 
    * @var bool
    */
	var $cargaVista = true;
	/**
    * El menú del programa
    * @var zen_menu_gtk
    */
	var $menu = null ;
	/**
    * Los elementos del menú
    * @var array
    */
	var $menus= array();
	/**
    * El objeto que contiene el conjunto de todos los componentes visuales del programa 
    * @var GtkVBox
    */
	var $contenedor = null;
	/**
    * Las referencias a los objetos del programa como array
    * @var array
    */
	var $widgets;
	/**
    * Clase que analiza los ficheros cartuchos XML
    * @var zen_analizador_cartucho
    */
	var $analizador;
	/**
    * Especifica si añadir el motor zenphp al generar un proyecto de aplicación
    * @var bool
    */
	var $incluir_zenphp = true;
	/**
    * Variable para saber si hemos cargado algún cartucho en memoria _con éxito_!
    * @var str
    */
	var $cartucho_actual= "";
	/**
	 * Administrador de bases de datos mySQL
	 *
	 * @var zen_gtk_ventana_mysql_admin
	 */
	var $mysql_admin;
	/**
	 * Colores para colorear el código si es PHP
	 * @var array
	 */
	static protected $colores = array("blue", "red", "orange", "darkgreen", "black");
	/**
    * Constructor
    * @return zen_ventana_principal
    */
	function zen_ventana_principal(){
		//Inicializaciones
		parent::__construct();
		$this->widgets = array();
		//Ahora podemos asociar la ventana al analizador
		$this->analizador =& new zen_analizador_cartucho($this);
		$this->connect_simple('destroy', array('Gtk', 'main_quit'));
		$this->contenedor =& new GtkVBox(false); //No homogéneo...
		//Crea los menús...
		$this->asociar_menus();
		//Añadir contenedor principal:
		$this->contenedor->add($this->__crear_navegador());
		$this->add($this->contenedor);
		
		//Parámetros de la ventana principal:
		$this->set_title("Generador de aplicaciones de zenphp::".__CLASS__);
		$this->set_default_size(500, 400);
		$this->set_position(Gtk::WIN_POS_CENTER);
		//Mostrar
		$this->show_all();
		
	}
	/**
    * Construye los menús a partir de un fichero XML y los asocia a la ventana principal
    */ 
	function asociar_menus(){
		$this->menu =& new zen_menu_gtk();
		$this->menu->crear_desde_xml("zen_generador.xml");
		$this->menu->set_size_request(135,24);

		$this->connect_simple('destroy', array('Gtk', "main_quit"));
		$this->menus['abrir'] = $this->menu->obtenerWidget("mnu_abrir");
		$this->menus['abrir'] -> connect_simple("activate", "evento_menu", "mnu_abrir");

		$this->menus['guardar'] = $this->menu->obtenerWidget("mnu_guardar");
		$this->menus['guardar']->connect_simple("activate", "evento_menu", "mnu_guardar");

		$this->menus['generar'] = $this->menu->obtenerWidget("mnu_generar");
		$this->menus['generar']->connect_simple("activate", "evento_menu", "mnu_generar");

		$this->menus['cerrar'] = $this->menu->obtenerWidget("mnu_cerrar");
		$this->menus['cerrar']->connect_simple("activate", "evento_menu", "mnu_cerrar");


		$this->menus['salir'] = $this->menu->obtenerWidget("mnu_salir");
		$this->menus['salir']->connect_simple("activate", "salir_generador");

		$this->menus['cortar'] = $this->menu->obtenerWidget("mnu_cortar");
		$this->menus['cortar']->connect_simple("activate", "evento_menu", "mnu_cortar");

		$this->menus['copiar'] = $this->menu->obtenerWidget("mnu_copiar");
		$this->menus['copiar']->connect_simple("activate", "evento_menu", "mnu_copiar");

		$this->menus['pegar'] = $this->menu->obtenerWidget("mnu_pegar");
		$this->menus['pegar']->connect_simple("activate", "evento_menu", "mnu_pegar");

		$this->menus['personal'] = $this->menu->obtenerWidget("mnu_personal");
		$this->menus['personal']->connect_simple("activate", "evento_menu", "mnu_personal");

		$this->menus['submenu']= $this->menu->obtenerWidget("mnu_submenuitem");
		$this->menus['submenu']->connect_simple("activate", "evento_menu", "submenuItem");
		$this->contenedor->pack_start($this->menu,false,false,false);
	}

	/**
  * Genera la interfaz del generador con un panel 
  */
	function __crear_navegador()
	{
		$w =& $this->widgets; //para reducir el nombre ;)
		$w['navegador'] =& new GtkVBox();
		$w['navegador']->pack_start(new GtkLabel('Doble click para abrir el cartucho, o seleccionarlo y pulsar ENTER'), false);

		$w['panel_horizontal'] =& new GtkHPaned();
		$w['panel_horizontal']->set_position(200);
		//Cartuchos:
		//nombre del fichero, selección, ruta completa, comprobar si es directorio, imagen de previsualización
		$w['fichero_seleccionado'] =& new GtkListStore(GObject::TYPE_STRING, GObject::TYPE_STRING, GObject::TYPE_STRING, GObject::TYPE_BOOLEAN, GdkPixbuf::gtype);
		$w['fichero_seleccionado']->set_sort_column_id(0, Gtk::SORT_ASCENDING);

		$w['vista_arbol'] =& new GtkTreeView($w['fichero_seleccionado']);
		$w['columna_vista_arbol'] =& new GtkTreeViewColumn(
		'Imagen',
		new GtkCellRendererPixbuf(),
		'pixbuf',
		4
		);
		$texto =& new GtkCellRendererText();
		$w['columna_vista_arbol']->pack_start($texto);
		$w['columna_vista_arbol']->add_attribute($texto, 'markup', 1);
		$w['vista_arbol']->append_column($w['columna_vista_arbol']);
		$w['vista_arbol']->set_headers_visible(false);

		$w['vista_arbol']->connect('key-press-event', array($this, 'seleccion_fichero'));
		$w['vista_arbol']->connect('button-press-event', array($this, 'seleccion_fichero'));
		$this->cargar_ficheros($w['fichero_seleccionado'], getcwd());

		$w['lista_ficheros'] =& new GtkScrolledWindow();
		$w['lista_ficheros']->add($w['vista_arbol']);
		$w['lista_ficheros']->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);

		$w['navegador_fichero'] =& new GtkVBox();
		$w['navegador_fichero']->pack_start($w['lista_ficheros']);

		$w['comprobar_inclusion_zf'] =& new GtkCheckbutton('Incluir el motor zenphp en el directorio de salida');
		$w['comprobar_inclusion_zf']->set_active(true);
		$w['comprobar_inclusion_zf']->connect('toggled', array($this, 'marcar_inclusion'));
		$w['navegador_fichero']->pack_start($w['comprobar_inclusion_zf'], false);
		$w['panel_horizontal']->add1($w['navegador_fichero']);
		$this->widgets['imagen'] =& new GtkImage();
		$w['bloc_notas'] =& new GtkNotebook();
		$w['frame_1_bloc_notas'] = & new GtkScrolledWindow();
		$w['frame_2_bloc_notas'] = & new GtkFrame("Configurar cartucho (leido del XML)");
		$w['frame_3_bloc_notas'] = & new GtkFrame("Detalles del valor seleccionado");
		$w['frame_4_bloc_notas'] = & new GtkFrame("Acerca...");
		$w['frame_1_bloc_notas']->add_with_viewport($this->widgets['imagen']);
		$w['frame_1_bloc_notas']->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
		$modelo = $this->crear_modelo_arbol();
		$w['arbol_propiedades_cartucho'] =& new GtkTreeView($modelo);
		$this->configurar_arbol();
		$scrolled = new GtkScrolledWindow();
        $scrolled->set_shadow_type(Gtk::SHADOW_ETCHED_IN);
        $scrolled->set_policy(Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
        $scrolled->add($w['arbol_propiedades_cartucho']);
        //$w['frame_2_bloc_notas']->pack_start($scrolled, false, false, 0);
    	$w['frame_2_bloc_notas']->add($scrolled);
    	/** @todo: Pasar todos las construcciones a la fábrica de objetos */
    	list($w['caja_codigo'],$w['buffer_codigo']) = $this->crear_caja_texto_fuente();
    	$w['frame_3_bloc_notas']->add($w['caja_codigo']);
    	$w['frame_4_bloc_notas']->add(new GtkLabel('Acerca del cartucho'));
    	$w['bloc_notas']->append_page($w['frame_1_bloc_notas'], new GtkLabel("Imagen previsualiza"));
    	$w['bloc_notas']->append_page($w['frame_2_bloc_notas'], new GtkLabel("Configurar cartucho"));
    	$w['bloc_notas']->append_page($w['frame_3_bloc_notas'], new GtkLabel("Detalles..."));
    	$w['bloc_notas']->append_page($w['frame_4_bloc_notas'], new GtkLabel("Acerca de..."));	
		$w['panel_horizontal']->add2($w['bloc_notas']);
		$w['navegador']->pack_end($w['panel_horizontal']);
		return $w['navegador'];
	}
	
	private function configurar_arbol(){
		$treeview =& $this->widgets['arbol_propiedades_cartucho'];
		$column = new GtkTreeViewColumn();
        $column->set_title('Icono y nombre');

        $cell_renderer = new GtkCellRendererPixbuf();
        $column->pack_start($cell_renderer, false);
        $column->set_attributes($cell_renderer, 'stock-id', 1);

        $cell_renderer = new GtkCellRendererText();
        $column->pack_start($cell_renderer, true);
        //$column->set_cell_data_func($cell_renderer, 'constant_setter');

        $treeview->append_column($column);

        $cell_renderer = new GtkCellRendererText();
        //$treeview->insert_column_with_data_func(-1, 'Etiqueta', $cell_renderer, 'label_setter');

        $cell_renderer = new GtkCellRendererText();
        //$treeview->insert_column_with_data_func(-1, 'Valor', $cell_renderer, 'accel_setter');

        $cell_renderer = new GtkCellRendererText();
        //$treeview->insert_column_with_data_func(-1, 'ID', $cell_renderer, 'id_setter');
        $display = new StockItemDisplay();
        $treeview->set_data('stock-display', $display);

        $display->type_label = new GtkLabel();
        $display->constant_label = new GtkLabel();
        $display->id_label = new GtkLabel();
        $display->accel_label = new GtkLabel();
        $display->icon_image = new GtkImage();

        $selection = $treeview->get_selection();
        $selection->set_mode(Gtk::SELECTION_SINGLE);

	}
	private function crear_modelo_arbol()
    {
        $store = new GtkListStore(GObject::TYPE_PHP_VALUE, GObject::TYPE_STRING);

        $ids = Gtk::stock_list_ids();
        sort($ids);

        foreach ($ids as $id) {
            $info = new StockItemInfo($id);
            $stock_item = Gtk::stock_lookup($id);
            if ($stock_item)
                $info->stock_item = $stock_item;
            else
                $info->stock_item = array('', '', 0, 0, '');

            $icon_set = GtkIconFactory::lookup_default($id);
            if ($icon_set) {
                $sizes = $icon_set->get_sizes();
                $size = $sizes[0];
                for ($i = 0; $i < count($sizes); $i++) {
                    if ($sizes[$i] == Gtk::ICON_SIZE_MENU) {
                        $size = Gtk::ICON_SIZE_MENU;
                        break;
                    }
                }
                $info->small_icon = $this->render_icon($info->stock_id, $size);
                if ($size != Gtk::ICON_SIZE_MENU) {
                    list($width, $height) = Gtk::icon_size_lookup(Gtk::ICON_SIZE_MENU);

                    $info->small_icon = $info->small_icon->scale_simple($width, $height, 'bilinear');
                }

            } else {
                $info->small_icon = null;
            }

            if ($info->stock_item[3] == 0) {
                $info->accel_str = '';
            } else {
                $info->accel_str = '<'.Gtk::accelerator_get_label($info->stock_item[3], $info->stock_item[2]).'>';
            }

            $iter = $store->append();
            $store->set($iter, 0, $info, 1, $id);
        }

        return $store;
    }
	
	function crear_caja_texto_fuente(){
		$texto  =& new GtkTextView();
        $buffer =& new GtkTextBuffer();
        $texto->set_buffer($buffer);
        $texto->set_editable(true);
        $texto->set_cursor_visible(true);
        $tag_table = $buffer->get_tag_table();	
        foreach(self::$colores as $color) {
            $tag = new GtkTextTag($color);
            $tag->set_property("foreground", $color);
            $tag_table->add($tag);
        }
        
        return array($texto, $buffer);
	}

	/**
    * Muestra la información formateada del directorio seleccionado
    * @param GtkListStore $fichero_seleccionado
    * @param str $directorio
    */
	function cargar_ficheros(&$fichero_seleccionado, $directorio){
		$manejador = dir($directorio);
		$fichero_seleccionado->clear();

		while (false !== ($fichero = $manejador->read())) {
			if ($fichero==".") continue;
			$obj_imagen = null;
			$ruta = $manejador->path . DIRECTORY_SEPARATOR . $fichero;
			if (is_dir($ruta) && $fichero !== '.') {
				$this->poner_imagen_icono($obj_imagen,'img/directorio.jpg');
				$fichero_seleccionado->append(array($fichero, '<span color="#00F">' . $fichero . '</span>', $ruta, true, $obj_imagen));
				continue;
			} elseif (substr($ruta, -4) == '.xml') {
				if ($this->cargaVista){ //Precarga del fichero...etc
				 $r = $this->analizador->lee_previsualizacion_del_cartucho($ruta,$obj_imagen); //Carga la previsualización del XML del cartucho
				}
				if (!$r || $obj_imagen==null) $this->poner_imagen_icono($obj_imagen,'img/xml.gif');
			} else {
				$this->poner_imagen_icono($obj_imagen,'img/fichero.png');
			}
			$fichero_seleccionado->append(array($fichero, $fichero, $ruta, false, $obj_imagen));
		}
	}
	/**
	 * Pone la $imagen dada como icono al elemento de la lista de ficheros $pb
	 *
	 * @param GdkPixbuf $pb
	 * @param str $imagen
	 */
	function poner_imagen_icono( &$pb, $imagen='img/fichero.png' ){
		$pb = GdkPixbuf::new_from_file($imagen)->scale_simple(32, 32, Gdk::INTERP_BILINEAR);
	}
	/**
    * Evento de selección de un fichero, se comprueba si es un cartucho
    * @param GtkTreeView $vista_arbol
    * @param callback $evento
    */
	function seleccion_fichero($vista_arbol, $evento) {
		if (
		($evento->type == Gdk::KEY_PRESS && $evento->keyval == Gdk::KEY_Return)
		|| ($evento->type == Gdk::_2BUTTON_PRESS && $evento->button == 1)
		) {
			list($modelo, $iter) = $vista_arbol->get_selection()->get_selected();
			if ($iter !== null) {
				$ruta = $modelo->get_value($iter, 2);
				if ($modelo->get_value($iter, 3)) {
					$this->cargar_ficheros($modelo, $ruta);
				} else { //Es un fichero
					if (strtolower(substr($ruta, -4))== '.xml') //Solo cargar XML al seleccionarlos
					 $this->analizador->cargar_cartucho($ruta);
				}
			}
		}
	}


	/**
    * Marca la inclusión del motor zenphp
    * @param GtkCheckbutton $comprobar_inclusion_zf
    */
	public function marcar_inclusion(&$comprobar_inclusion_zf){
		$this->incluir_zenphp = $comprobar_inclusion_zf->get_active();
	}
	//Recordar que se pueden tomar imágenes de otros cartuchos por eso es necesaria la ruta absoluta en los ficheros especificados en
	// el XML

	
	/**
	 * Pone la $imagen al $this->widgets['imagen'] (GtkImage) del viewport del primer panel del GtkNotebook (ver kksou PHP-GTK Explorer)
	 * @param str $imagen
	 */
	function poner_imagen($imagen=""){
		if (ZF_GTK_MODO_DEBUG)
		 print_r(array_keys($this->widgets));
		if (empty($imagen)||!is_readable($imagen)) {
			trigger_error("No se puede leer la imagen $imagen",E_USER_WARNING);
		} else {
			//GtkImage:
			$this->widgets['imagen']->set_from_file($imagen);
		}
	}
}
class StockItemDisplay {
    public $type_label;
    public $constant_label;
    public $id_label;
    public $accel_label;
    public $icon_image;
}

class StockItemInfo {
    public $stock_id = '';
    public $stock_item = null;
    public $small_icon = null;
    public $constant = '';
    public $accel_str = '';

    function __construct($stock_id = null) {
        $this->stock_id = $stock_id;
        if ($stock_id) {
            $this->constant = id_to_constant($stock_id);
        }
    }
}
function id_to_constant($id)
{
    if (substr($id, 0, 3) == 'gtk') {
        $constant = 'Gtk::STOCK' . preg_replace('!-([^-]+)!e', '"_".strtoupper("$1")', substr($id, 3));
    } else {
        $constant = substr(preg_replace('!([^-]+)-?!e', 'strtoupper($1)', $id), 1);
    }

    return $constant;
}

?>